package com.example.security.security;

import com.example.security.entity.UserEntity;
import com.example.security.entity.UserRoleEntity;
import com.example.security.repository.UserRepository;
import com.example.security.repository.UserRoleRepository;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author : zhayh
 * @date : 2021-4-18 17:10
 * @description : 令牌工具类
 */

@Component
public class TokenProvider {
    @Resource
    private UserRepository userRepository;

    @Resource
    private UserRoleRepository userRoleRepository;

    /**
     * 通过SpringSecurity登录通过的Authentication独享，产生token
     *
     * @param user 登录通过的用户对象
     * @return 用户令牌
     */
    public String createToken(Authentication user) {
        List<SimpleGrantedAuthority> roles = (List<SimpleGrantedAuthority>) user.getAuthorities();
        // 使用登录名加上"thisisatoken."前缀作为用户令牌
        return "thisisatoken." + user.getName() + "." + roles.toString();
    }

    // 校验用户令牌是否合法
    public boolean validateToken(String token) {
        return token.startsWith("thisisatoken");
    }

    public Authentication getUser(String token) {
        // 1. 解析令牌。的搭配SpringSecurity能够使用的Authentication，实现逻辑与UserDetailService类似
        String login = token.split("\\.")[1];
        // 2. 获取账户对应角色
        String roleStr = token.split("\\.")[2];
        roleStr = roleStr.replace("[", "").replace("]", "");
        String[] roles = roleStr.split(",");
        // 3. 将账户角色组成SpringSecurity的权限列表
        List<SimpleGrantedAuthority> roleList = Arrays.stream(roles).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
        // 4. 构造为SpringSecurity的验证对象，并返回交给Spring Security进行校验
        return new UsernamePasswordAuthenticationToken(login, token, roleList);
    }
}
